package com.common.db;

import java.sql.Connection;
import java.util.ArrayList;
import java.util.Set;
import java.util.HashMap;

import com.common.shared.usermanager.Group;
import com.common.shared.usermanager.Permission;
import com.common.shared.usermanager.PermitionTable;
import com.common.shared.usermanager.SUser;
import com.common.shared.usermanager.User;
import com.common.shared.usermanager.UserGroup;

public class UserManager {

	private static UserManager instance;

	private HashMap<String, Permission> tmPermissionNames = new HashMap<String, Permission>();
	private HashMap<Integer, Permission> tmPermissionIds = new HashMap<Integer, Permission>();
	private HashMap<String, Group> tmGroupNames = new HashMap<String, Group>();
	private HashMap<Integer, Group> tmGroupIds = new HashMap<Integer, Group>();
	private HashMap<String, SUser> tmUserNames = new HashMap<String, SUser>();
	private HashMap<Integer, SUser> tmUserIds = new HashMap<Integer, SUser>();

	public UserManager(String dbName, Connection connection) throws Exception {
		Connection conn = null;
		try {
			conn = connection == null ? DBConnection.getConnection(dbName)
					: connection;

			setData(DBConnection.getAllPermitionTables(dbName, conn),
					DBConnection.getAllGroups(dbName, conn),
					DBConnection.getAllPermisions(dbName, conn),
					DBConnection.getAllUsers(dbName, conn),
					DBConnection.getAllUserGroups(dbName, conn));
		} catch (Exception e) {
			// TODO: handle exception
		} finally {
			try {
				if (connection == null)
					DBConnection.freeConnection(conn);
			} catch (Exception e2) {
				// TODO: handle exception
			}
		}

	}

	public void setData(ArrayList<PermitionTable> PermissionTables,
			ArrayList<Group> groups, ArrayList<Permission> Permissions,
			ArrayList<User> users, ArrayList<UserGroup> userGroups) {
		instance = this;

		for (User user : users) {
			SUser su = new SUser();
			su.setUser(user);
			tmUserNames.put(user.getUsername(), su);
			tmUserIds.put(user.getId(), su);
		}

		for (Permission Permission : Permissions) {
			tmPermissionNames.put(Permission.getPermission_name(), Permission);
			tmPermissionIds.put(Permission.getId(), Permission);
		}

		for (Group group : groups) {
			tmGroupNames.put(group.getGroup_name(), group);
			tmGroupIds.put(group.getId(), group);
		}
		for (PermitionTable PermitionTable : PermissionTables) {
			if (!PermitionTable.isUserperm()) {
				Group gr = tmGroupIds.get(PermitionTable.getUser_or_group_id());
				if (gr == null)
					continue;
				Permission prm = tmPermissionIds.get(PermitionTable
						.getPermition_id());
				if (prm == null)
					continue;
				if (PermitionTable.isAccepted())
					gr.getPermitions().add(prm);

			} else {
				SUser usr = tmUserIds.get(PermitionTable.getUser_or_group_id());
				if (usr == null)
					continue;
				Permission prm1 = tmPermissionIds.get(PermitionTable
						.getPermition_id());
				if (prm1 == null)
					continue;
				if (PermitionTable.isAccepted())
					usr.getPermitions().add(prm1);
			}
		}

		for (UserGroup userGroup : userGroups) {
			Group gr = tmGroupIds.get(userGroup.getGroup_id());
			if (gr == null)
				continue;
			SUser usr = tmUserIds.get(userGroup.getUser_id());
			if (usr == null)
				continue;
			usr.getGroups().add(gr);
		}

		for (PermitionTable PermitionTable : PermissionTables) {
			if (!PermitionTable.isUserperm()) {
				Group gr = tmGroupIds.get(PermitionTable.getUser_or_group_id());
				if (gr == null)
					continue;
				if (!PermitionTable.isAccepted())
					gr.removePermition(PermitionTable.getPermition_id());
			}
		}

		for (Group group : groups) {
			group.regeneratePermitions();
		}

		Set<Integer> userIds = tmUserIds.keySet();
		for (Integer userId : userIds) {
			SUser usr = tmUserIds.get(userId);
			if (usr == null)
				continue;
			ArrayList<Group> grps = usr.getGroups();
			for (Group group : grps) {
				ArrayList<Permission> grPerm = group.getPermitions();
				for (Permission Permission : grPerm) {
					usr.addPermitionIfNotExists(Permission);
				}
			}
		}
		for (PermitionTable permitionTable : PermissionTables) {
			if (permitionTable.isUserperm()) {
				SUser usr = tmUserIds.get(permitionTable.getUser_or_group_id());
				if (usr == null)
					continue;
				if (!permitionTable.isAccepted())
					usr.removePermition(permitionTable.getPermition_id());
			}
		}
		for (Integer userId : userIds) {
			SUser usr = tmUserIds.get(userId);
			if (usr == null)
				continue;
			usr.regeneratePermitionsAndGroups();
		}

	}

	public static UserManager getInstance() {
		// if (instance == null) {
		// ArrayList<Permission> Permissions = new ArrayList<Permission>();
		// for (int i = 0; i < 10; i++) {
		// Permission Permission = new Permission();
		// Permission.setId(i + 1);
		// Permission.setCaption_id(1);
		// Permission.setPermission_name("Permission_" + (i + 1));
		// Permissions.add(Permission);
		// }
		// ArrayList<Group> groups = new ArrayList<Group>();
		// for (int i = 0; i < 10; i++) {
		// Group group = new Group();
		// group.setId(i + 1);
		// group.setCaption_id(1);
		// group.setGroup_name("GROUP" + (i + 1));
		// groups.add(group);
		// }
		//
		// ArrayList<User> users = new ArrayList<User>();
		// for (int i = 0; i < 10; i++) {
		// User user = new User();
		// user.setId(i + 1);
		// user.setUsername("USER" + (i + 1));
		// users.add(user);
		// }
		// new UserManager(new ArrayList<GroupPermission>(), groups,
		// Permissions, users, new ArrayList<UserPermission>());
		// }
		return instance;
	}

	public HashMap<String, Permission> getTmPermissionNames() {
		return tmPermissionNames;
	}

	public HashMap<Integer, Permission> getTmPermissionIds() {
		return tmPermissionIds;
	}

	public HashMap<String, Group> getTmGroupNames() {
		return tmGroupNames;
	}

	public HashMap<Integer, Group> getTmGroupIds() {
		return tmGroupIds;
	}

	public HashMap<String, SUser> getTmUserNames() {
		return tmUserNames;
	}

	public HashMap<Integer, SUser> getTmUserIds() {
		return tmUserIds;
	}

}
